﻿using Extended.WPF.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;

namespace Extented.UI.Core.Themes
{
    public abstract class ThemeKeyExtensionGeneric : ResourceKey {
		static ThemeKeyExtensionGeneric() {
			if(System.Windows.Interop.BrowserInteropHelper.IsBrowserHosted && !OptionsXBAP.SuppressNotSupportedException)
				throw new XbapNotSupportedException(XbapNotSupportedException.Text);
		}

		protected static readonly object defaultResourceCore = new object();
		protected ThemeKeyExtensionGeneric() {
			resourceKeyCore = defaultResourceCore;
		}
		int hash;
		object resourceKeyCore;
		string themeName;
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public Type TypeInTargetAssembly { get; set; }
		public string ThemeName {
			get { return themeName; }
			set { SetThemeName(value); }
		}
		protected object ResourceKeyCore { get { return resourceKeyCore; } set { resourceKeyCore = value; } }
		void SetThemeName(string value) {
			themeName = value;
			SetHashCode();
		}
		public override int GetHashCode() {
			return hash;
		}
		protected virtual bool Equals(ThemeKeyExtensionGeneric other) {
			if (IsSameTheme(other)) 
				return true;
			return false;
		}
		protected virtual bool IsSameTheme(ThemeKeyExtensionGeneric other) {
			bool equals = object.Equals(ThemeName, other.ThemeName);
			if (@equals)
				return true;
			if (CompareWithAlias(ThemeName, other.ThemeName) || CompareWithAlias(other.ThemeName, ThemeName))
				return true;
			return false;
		}
		public override bool Equals(object obj) {
			if (ReferenceEquals(null, obj))
				return false;
			if (ReferenceEquals(this, obj))
				return true;
			if (obj.GetType() != this.GetType())
				return false;
			return Equals((ThemeKeyExtensionGeneric)obj);
		}
		bool CompareWithAlias(string themeName0, string themeName1) {
			return string.IsNullOrEmpty(themeName0) && (string.IsNullOrEmpty(themeName1) || themeName1 == Theme.DeepBlueName);
		}
		public virtual string ResourceKeyToString() {
			return resourceKeyCore.ToString();
		}
#if !SILVERLIGHT
		public override System.Reflection.Assembly Assembly {
			get {
				if(TypeInTargetAssembly != null) {
					return TypeInTargetAssembly.Assembly;
				}
				return string.IsNullOrEmpty(ThemeName) ? GetType().Assembly : GetAssembly();
			}
		}
		protected virtual System.Reflection.Assembly GetAssembly() {
			Theme theme = Theme.FindTheme(ThemeName);
			if(theme == null)
				return null;
			return theme.Assembly;
		}
		public override object ProvideValue(IServiceProvider serviceProvider) {
			if(string.IsNullOrEmpty(ThemeName)) {
				string themeName = ThemeNameHelper.GetThemeName(serviceProvider);
				if(!string.IsNullOrEmpty(themeName))
					ThemeName = themeName;
			}
			return this;
		}
#endif
		protected virtual void SetHashCode() {
			hash = GenerateHashCode();
		}
		protected virtual int GenerateHashCode() {
			return 0;
		}
		bool ShouldSerializeThemeName() {
			return !String.IsNullOrEmpty(ThemeName);
		}		
	}
}
